﻿<!-- 修改于2024-10-23 恢复divider类型按钮 -->
<!-- 修改于2024-10-22 meta类型选择框展示问题 -->
<!-- 修改于2024-09-20 修正选择框无法展示问题 -->
<!-- 修改于2024-06-07 新增表头提示功能 -->
<style>
.head-cell-text {
  padding: 0;
  margin: 0;
  font-weight: 700;
}
</style>
<template>
  <el-table-column v-if="field&&field.type=='selection'" type="selection" :width="width?width:25"
                   :show-overflow-tooltip="field.showOverflowTooltip==true" :fixed="field.fixed">
  </el-table-column>
  <el-table-column v-else-if="field&&field.type=='index'" type="index" :width="columnWidthMap[field.id]"
                   :show-overflow-tooltip="field.showOverflowTooltip==true" :fixed="field.fixed">
  </el-table-column>
  <el-table-column v-else-if="field&&field.type=='button'" header-align="center" :align="field.align?field.align:'center'" :label="field.name"
        :width="columnWidthMap[field.id]" :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true" :fixed="field.fixed">
    <template v-if="field.header&&field.header.type=='button'&&field.header.children&&field.header.children.length>0" #header>
      <el-button v-for="item in field.header.children" :key="timestamp+'_header_btn'+item.text" :type="item.type?item.type:'default'" size="mini"
                 :disabled="item.isDisabled?item.isDisabled():false" :style="{display:(item.isHide&&item.isHide())?'none':'inline-block'}"
                 @click="handleButtonClick(item)">{{item.text}}</el-button>
    </template>
        <template slot-scope="scope">
            <div v-if="field.children&&field.children.length>0" style="padding: 3px 0 3px 0;">
              <template v-for="item in field.children">
                <template v-if="!(item.isHide&&item.isHide(scope.row))">
                  <el-dropdown v-if="item.children&&item.children.length>0"
                               @command="(command)=>{item.handleCommand(command,scope.row,item.children)}"
                               style="margin-left:5px;">
                    <el-button style="padding-left: 7px;padding-right: 5px;" size="mini">
                      {{ item.text }}<i class="el-icon-arrow-down el-icon--right"></i>
                    </el-button>
                    <el-dropdown-menu slot="dropdown">
                      <el-dropdown-item v-for="subItem of item.children" :command="subItem.text">{{ subItem.text }}</el-dropdown-item>
                    </el-dropdown-menu>
                  </el-dropdown>
                  <el-divider v-else-if="item.type=='divider'" direction="vertical"></el-divider>
              <el-button v-else :key="timestamp+'_row_btn'+item.text+scope.$index" :type="item.type?item.type:'default'" size="mini"
                         :disabled="item.isDisabled?item.isDisabled(scope.row):false"
                         @click="handleButtonClick(item,scope.row)">{{item.text}}</el-button>
                </template>
              </template>
            </div>
        </template>
  </el-table-column>
  <!-- 处理组织机构列类型 -->
  <el-table-column v-else-if="field&&field.type=='office'" header-align="center" :align="field.align?field.align:'center'" :label="field.name"
        :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true" :fixed="field.fixed">
        <template slot-scope="scope">
          {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][scope.row[field.id]])?fieldDataNameMap[field.id][scope.row[field.id]]:scope.row[field.id]}}
        </template>
  </el-table-column>
  <!-- 处理用户列类型 -->
  <el-table-column v-else-if="field&&field.type=='user'" header-align="center" :align="field.align?field.align:'center'" :label="field.name"
        :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true" :fixed="field.fixed">
        <template slot-scope="scope">
          {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][scope.row[field.id]])?fieldDataNameMap[field.id][scope.row[field.id]]:scope.row[field.id]}}
        </template>
  </el-table-column>
  <el-table-column v-else-if="field&&field.type=='meta'&&field.source" :key="'meta_'+timestamp+field.id" header-align="center"
                   :align="field.align?field.align:'center'" :label="field.name" :prop="field.id" :fixed="field.fixed"
        :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true">
        <template #header>
          <p class="head-cell-text">
            {{field.name}}
            <el-tooltip v-if="field.tooltip" effect="dark" :content="field.tooltip" placement="bottom">
              <i class='el-icon-question' />
            </el-tooltip>
          </p>
          <p v-if="fieldDataNameMap['unit-type'][field.unit]||field.unit" class="head-cell-text">
            ({{fieldDataNameMap['unit-type'][field.unit]?fieldDataNameMap['unit-type'][field.unit]:field.unit}})</p>
        </template>

        <template slot-scope="scope">
          <data-select v-if="!readonly&&!field.readonly" :data="fieldDataListMap[field.id]" v-model="scope.row[field.id]"
            @change="handleChangeInput(field,scope.row)" :class="(changeCellMap&&changeCellMap[field.id+':'+scope.row.rowNum])?'cell-changed':''"></data-select>
          <template v-else-if="scope.row[field.id] instanceof Array&&field.component&&field.component.id=='tag'">
          <template v-for="tagItem in scope.row[field.id]">
            <el-tag v-if="field.component.id=='tag'"
                    :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
              {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][tagItem])?fieldDataNameMap[field.id][tagItem]:tagItem}}
            </el-tag>
          </template>
          </template>
          <el-tag v-else-if="field.component&&field.component.id=='tag'"
                  :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
            {{fieldDataNameMap[field.id]?fieldDataNameMap[field.id][scope.row[field.id]]:scope.row[field.id]}}
          </el-tag>
            <span v-else
              :class="!selectArea||!selectArea.cellMap||!selectArea.cellMap[field.id+':'+scope.row.rowNum]?'':'cell-selected'">
              {{fieldDataNameMap[field.id]? (fieldDataNameMap[field.id][scope.row[field.id]] ? fieldDataNameMap[field.id][scope.row[field.id]] :scope.row[field.id]) :scope.row[field.id] }}
            </span>
        </template>
      </el-table-column>
  <el-table-column v-else-if="field&&field.component&&(field.component.id=='data-select'||field.component.id=='select')" :key="'dataselect_'+timestamp+field.id" header-align="center"
                   :align="field.align?field.align:'center'" :label="field.name" :prop="field.id" :fixed="field.fixed"
        :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true">
        <template #header>
          <p class="head-cell-text">
            {{field.name}}
            <el-tooltip v-if="field.tooltip" effect="dark" :content="field.tooltip" placement="bottom">
              <i class='el-icon-question' />
            </el-tooltip>
          </p>
          <p v-if="fieldDataNameMap['unit-type'][field.unit]||field.unit" class="head-cell-text">
            ({{fieldDataNameMap['unit-type'][field.unit]?fieldDataNameMap['unit-type'][field.unit]:field.unit}})</p>
        </template>

        <template slot-scope="scope">
          <data-select v-if="!readonly&&!field.readonly" :data="field.component.data" v-model="scope.row[field.id]"
            @change="handleChangeInput(field,scope.row)" :class="(changeCellMap&&changeCellMap[field.id+':'+scope.row.rowNum])?'cell-changed':''"></data-select>
            <data-name v-else :data="field.component.data"
              :class="!selectArea||!selectArea.cellMap||!selectArea.cellMap[field.id+':'+scope.row.rowNum]?'':'cell-selected'">
            </data-name>
        </template>
      </el-table-column>
  <el-table-column v-else-if="field&&field.type=='name-display'&&field.dataUrl" :key="'namedisplay_'+timestamp+field.id" header-align="center"
                   :align="field.align?field.align:'center'" :label="field.name" :prop="field.id" :fixed="field.fixed"
        :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true">
    <!-- 处理根据接口转换id为名称显示列 -->
        <template slot-scope="scope">
          <template v-if="typeof(scope.row[field.id])=='array'">
            <template v-for="tagItem in scope.row[field.id]">
            <el-tag v-if="field.component.id=='tag'"
                    :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
              {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][tagItem])?fieldDataNameMap[field.id][tagItem]:tagItem}}
            </el-tag>
            <span v-else>
              {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][tagItem])?fieldDataNameMap[field.id][tagItem]:tagItem}}
            </span>
            </template>
          </template>
          <template v-else>
            <el-tag v-if="field.component.id=='tag'"
                    :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
              {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][scope.row[field.id]])?fieldDataNameMap[field.id][scope.row[field.id]]:scope.row[field.id]}}
            </el-tag>
            <span v-else>
              {{(fieldDataNameMap[field.id]&&fieldDataNameMap[field.id][scope.row[field.id]])?fieldDataNameMap[field.id][scope.row[field.id]]:scope.row[field.id]}}
            </span>

          </template>
        </template>
      </el-table-column>
  <el-table-column v-else-if="field&&field.type=='name-display'&&field.nameKey" :key="'namedispalykey_'+timestamp+field.id" header-align="center"
                   :align="field.align?field.align:'center'" :label="field.name" :prop="field.id" :fixed="field.fixed"
                   :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true">
    <!-- 根据列属性展示值 -->
    <template slot-scope="scope">
      <template v-if="scope.row[field.id] instanceof Array">
        <template v-for="subItem in scope.row[field.id]">
          <el-tag v-if="field.component.id=='tag'"
                  :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
            {{subItem[field.nameKey]}}
          </el-tag>
          <span v-else>
              {{subItem[field.nameKey]}}
            </span>
        </template>
      </template>
      <template v-else>
        <el-tag v-if="field.component.id=='tag'"
                :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
          {{scope.row[field.id][field.nameKey]}}
        </el-tag>
        <span v-else>
              {{scope.row[field.id][field.nameKey]}}
            </span>

      </template>
    </template>
  </el-table-column>
  <el-table-column v-else-if="field" :key="'col'+timestamp+field.id" :align="field.align?field.align:'center'"
                   :fixed="field.fixed" header-align="center" :label="field.name" :prop="field.id"
        :width="columnWidthMap[field.id]"  :min-width="field.minWidth?field.minWidth:40" :show-overflow-tooltip="field.showOverflowTooltip==true">
        <template #header>
          <p class="head-cell-text">
            {{field.name}}
            <el-tooltip v-if="field.tooltip" effect="dark" :content="field.tooltip" placement="bottom">
              <i class='el-icon-question' />
            </el-tooltip>
          </p>
          <p v-if="fieldDataNameMap['unit-type'][field.unit]||field.unit" class="head-cell-text">
            ({{fieldDataNameMap['unit-type'][field.unit]?fieldDataNameMap['unit-type'][field.unit]:field.unit}})</p>
        </template>
      <el-table-column-extend v-if="field.children&&field.type!='button'" v-for="subField in field.children"
                              :cell-readonly="cellReadonly"
                              :readonly="readonly"
                              :cell-change="cellChange"
                              :change-cell-map="changeCellMap"
                              :key="timestamp+'_subfield_'+subField.id"
                              :field="subField"  @handleEscClick="handleEscClick" @handleDeleteClick="handleDeleteClick"
                              @handleEnterClick="handleEnterClick" @handleMouseUp="handleMouseUp"
                              @handleMouseDown="handleMouseDown" @handlePaste="handlePaste"  :columnWidthMap="columnWidthMap"
                              :field-data-name-map="fieldDataNameMap"
                              :field-data-list-map="fieldDataListMap">
      </el-table-column-extend>

    <!-- 此处不可用v-else，否则无法起作用 -->
        <template v-if="!field.children||field.type=='button'" slot-scope="scope">
            <el-tag v-if="field.component&&field.component.id=='tag'"
                    :type="field.component.type?field.component.type:(field.component.getType?field.component.getType(scope.row[field.id]):'')">
              {{field.formatter?field.formatter(scope.row[field.id],scope.row):scope.row[field.id]+''}}
            </el-tag>
            <span v-else-if="field.readonly||readonly||(cellReadonly&&cellReadonly(scope.row,field))">
              {{field.formatter?field.formatter(scope.row[field.id],scope.row):scope.row[field.id]}}
            </span>
          <div v-else><span style="display: none;">{{scope.row[field.id]}}</span>
            <el-input :id="'input:'+field.id+':'+scope.row.rowNum" rows="1" placeholder=""
              v-model="scope.row[field.id]"
              :class="!selectArea||!selectArea.cellMap||!selectArea.cellMap[field.id+':'+scope.row.rowNum]?'':'cell-selected'"
              @paste.native.capture.prevent="handlePaste($event,field.id,scope.row)"
              @input="value=>processInputValue(scope.row,field,value)"
              @mousedown.native="handleMouseDown($event,field.id,scope.row)"
              @keydown.esc.native="handleEscClick($event,field.id,scope.row)"
              @keydown.delete.native="handleDeleteClick($event,field.id,scope.row)"
              @keydown.backspace.native="handleDeleteClick($event,field.id,scope.row)"
              @keydown.enter.native="handleEnterClick($event,field.id,scope.row)" :readonly="field.readonly||readonly"
                      @change="handleChangeInput(field,scope.row)"
            ></el-input>
          </div>
        </template>
      </el-table-column>

</template>

<script>
  export default {
    name: "ElTableColumnExtend",
    props: {

      field: {
      },
      fit:{
        type:Boolean,
        default:true,
      },
      //边框颜色
      borderColor:{
        type:String,
        default:''
      },
      //是否只读
      readonly:{
        type:Boolean,
        default:false,
      },
      //单元格是否只读
      cellReadonly:{
        type:Function,
        default:null,
      },
      //单元格数据变动事件
      cellChange:{
        type:Function,
        default:()=>{}
      },
      //选中区域
      selectArea:{

      },
      //数据变动单元格记录
      changeCellMap:{
      },
      columnWidthMap:{},
      fieldDataNameMap:{
        type:Object,
        default:{}
      },
      fieldDataListMap:{
        type:Object,
        default: {}
      },
      //宽度
      width:{},
      //对齐方式
      align:{
        type:String,
        default:'center'
      },
    },
    data() {
      return {
        timestamp:new Date().getTime(),
      }
    },

    watch: {
    },

    created: function () {
    },
    mounted: function () {
    },

    methods: {

      //处理粘贴事件
      handlePaste: function (event, fieldId, row) {
        this.$emit("handlePaste",event,fieldId,row);
        return true;
      },
      handleMouseDown: function (event, fieldId, row) {
        this.$emit("handleMouseDown",event,fieldId,row);
        return true;
      },
      handleEscClick: function (event, fieldId, row) {
        this.$emit("handleEscClick",event,fieldId,row);
      },
      //监听删除按钮按下，批量删除选中区域数据
      handleDeleteClick: function (event, columnId, row) {
        this.$emit("handleDeleteClick",event,columnId,row);

      },
      //监听回车按钮按下，输入框焦点下移
      handleEnterClick: function (event, fieldId, row) {
        this.$emit("handleEnterClick",event,fieldId,row);

      },
      //处理鼠标按键抬起事件
      handleMouseUp: function (event, fieldId, row) {
        this.$emit("handleMouseUp",event,fieldId,row);
        return true;
      },

      processInputValue: function (row, field, value) {
        if (field.dataType == 'number') {
          value = value.replace(/[^\d.-]/g, '');
          row[field.id] = value;
        }
      },


      //按钮点击响应
      handleButtonClick(button,row) {
        if(button.click) {
          button.click(row);
        } else {
          this.$message.warning("未绑定点击事件");
        }
      },
      //数据修改监听
      handleChangeInput(column,row) {
        if(column.change) {
          column.change(row);
        }
        if(this.cellChange){
          this.cellChange(column,row);
        }
      },
    }


  }
</script>